package com.efast.dmom.mgmt.service.les.impl;

import java.util.Date;
import java.util.List;

import com.efast.cafe.framework.exception.ServiceException;
import com.efast.cafe.framework.jdbc.JdbcDao;
import com.efast.cafe.framework.util.SpringWebUtils;
import com.efast.dmom.mgmt.bean.les.PdaTwDocAsnDetailsBean;
import com.efast.dmom.mgmt.dao.les.TwBasPartBatchDao;
import com.efast.dmom.mgmt.dao.les.TwBasPartBatchHeaderDao;
import com.efast.dmom.mgmt.dao.les.TwDocAsnDetailsDao;
import com.efast.dmom.mgmt.dao.les.TwDocAsnHeaderDao;
import com.efast.dmom.mgmt.dao.master.TmBasPartDao;
import com.efast.dmom.mgmt.dao.master.TrBasPartSupplDao;
import com.efast.dmom.mgmt.entity.les.TwBasPartBatch;
import com.efast.dmom.mgmt.entity.les.TwBasPartBatchHeader;
import com.efast.dmom.mgmt.entity.les.TwDocAsnDetails;
import com.efast.dmom.mgmt.entity.les.TwDocAsnHeader;
import com.efast.dmom.mgmt.entity.master.TmBasPart;
import com.efast.dmom.mgmt.entity.master.TrBasPartSuppl;
import com.efast.dmom.mgmt.entity.mes.TeProductInbound;
import com.efast.dmom.mgmt.service.les.TwDocAsnDetailsService;
import com.efast.dmom.mgmt.utils.Assist;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

/**
 * @author Administrator
 */
@Service("twDocAsnDetailsServiceImpl")
public class TwDocAsnDetailsServiceImpl implements TwDocAsnDetailsService {

	/**
	 * 收货单 TW_DOC_ASN_DETAILS
	 */
	private final TwDocAsnDetailsDao twDocAsnDetailsDao;
	/**
	 * 收货单 TW_DOC_ASN_HEADER
	 */
	private final TwDocAsnHeaderDao twDocAsnHeaderDao;
	/**
	 * tm_bas_part 零件基本信息
	 */
	private final TmBasPartDao tmBasPartDao;
	/**
	 * tr_bas_part_suppl 零件供应商关系
	 */
	private final TrBasPartSupplDao trBasPartSupplDao;
	private final TwBasPartBatchHeaderDao twBasPartBatchHeaderDao;
	private final TwBasPartBatchDao twBasPartBatchDao;
	
	@Qualifier("jdbcDao")
	@Autowired
	private JdbcDao jdbcDao;

	@Autowired
	public TwDocAsnDetailsServiceImpl(TwDocAsnDetailsDao twDocAsnDetailsDao, TwDocAsnHeaderDao twDocAsnHeaderDao,
			TwBasPartBatchHeaderDao twBasPartBatchHeaderDao, TwBasPartBatchDao twBasPartBatchDao,
			TmBasPartDao tmBasPartDao, TrBasPartSupplDao trBasPartSupplDao) {
		this.twDocAsnDetailsDao = twDocAsnDetailsDao;
		this.twDocAsnHeaderDao = twDocAsnHeaderDao;
		this.twBasPartBatchHeaderDao = twBasPartBatchHeaderDao;
		this.twBasPartBatchDao = twBasPartBatchDao;
		this.tmBasPartDao = tmBasPartDao;
		this.trBasPartSupplDao = trBasPartSupplDao;
	}

	/**
	 * 插入TwDocAsnDetails
	 * 
	 * @param value
	 *            TwDocAsnDetails
	 */
	@Override
	public void insertTwDocAsnDetails(TwDocAsnDetails value) {

		TwDocAsnHeader twDocAsnHeader = twDocAsnHeaderDao.selectTwDocAsnHeaderById(value.getTwDocAsnHeaderId());
		if (!("0".equals(twDocAsnHeader.getAsnSheetStatus()) || "1".equals(twDocAsnHeader.getAsnSheetStatus()))) {
			throw new ServiceException("header状态是" + twDocAsnHeader.getAsnSheetStatus() + ",不能新增");
		}
		List<TwDocAsnDetails> listTwDocAsnDetails = twDocAsnDetailsDao.selectTwDocAsnDetails(
				new Assist(Assist.andEq("tw_doc_asn_details.tw_doc_asn_header_id", value.getTwDocAsnHeaderId())));
		value.setAsnLineno(listTwDocAsnDetails.size() + 1);
		// ASN单证状态（新单0、部分收货1、收货完成2、拒绝收货3、收货取消4、单证关闭5
		value.setLineStatus("0");
		value.setAsnSheetNo(twDocAsnHeader.getAsnSheetNo());

		List<TrBasPartSuppl> listTrBasPartSuppl = trBasPartSupplDao.selectTrBasPartSuppl(
				new Assist(Assist.andEq("part_no_version", value.getPartNoVersion()),
						Assist.andEq("suppl_no", value.getSupplNo())));
		if (listTrBasPartSuppl.size() == 0) {
			throw new ServiceException(value.getPartNoVersion() + "零件没有查询到对应的零件供应商关系");
		}
		// 零件供应商关系ID
		value.setTrBasPartSupplId(listTrBasPartSuppl.get(0).getTrBasPartSupplId());

		List<TwBasPartBatchHeader> listTwBasPartBatchHeader = twBasPartBatchHeaderDao.selectTwBasPartBatchHeader(
				new Assist(Assist.andEq("tw_bas_part_batch_header.part_no_version", value.getPartNoVersion()),
						Assist.andEq("tw_bas_part_batch_header.suppl_no", value.getSupplNo())));

		if (listTwBasPartBatchHeader.size() == 0) {
			throw new ServiceException(value.getPartNoVersion() + "零件号，无法查询零件批次属性");
		}

		List<TwBasPartBatch> listTwBasPartBatch = twBasPartBatchDao.selectTwBasPartBatch(
				new Assist(Assist.andEq("tw_bas_part_batch.tw_bas_part_batch_header_id",
						listTwBasPartBatchHeader.get(0).getTwBasPartBatchHeaderId())));

		// 是否质检
		String a = "";
		for (TwBasPartBatch twBasPartBatch : listTwBasPartBatch) {
			if ("LOTATT05".equals(twBasPartBatch.getBatchOrder())) {
				a = twBasPartBatch.getIsUsedforLot();
			}
		}
		value.setLotatt02(listTwBasPartBatchHeader.get(0).getPlantNo());
		value.setLotatt03(listTwBasPartBatchHeader.get(0).getWorkshopNo());
		value.setLotatt04(listTwBasPartBatchHeader.get(0).getSupplNo());
		value.setLotatt05(a);

		// 如果新增ASN明细的时候没有填写收货包装流水号（托盘号），那么系统自动生成，生成规则是IS+yyyymmdd+seq
		// receive_pack_serial== 收货包装流水号
		String receivePackSerial = "";
		if (StringUtils.isBlank(value.getReceivePackSerial())) {
			receivePackSerial = jdbcDao.executeProcGetCode("tw_doc_asn_details", "efast");
			value.setReceivePackSerial(receivePackSerial);
		}
		// 如果新增ASN明细的时候没有填写零件包装流水号（箱号），那么系统自动生成，生成规则是入库包装流水号-1-1
		// part_pack_serial 零件包装流水号
		if (StringUtils.isBlank(value.getPartPackSerial())) {
			value.setPartPackSerial(receivePackSerial + "-1-1");
		}
		// inb_serial_no 库内跟踪流水号码 ==== 库内流水号等于收货流水号
		if (StringUtils.isBlank(value.getInbSerialNo())) {
			value.setInbSerialNo(receivePackSerial);
		}

		List<TmBasPart> listTmBasPart = tmBasPartDao.selectTmBasPart(
				new Assist(Assist.andEq("tm_bas_part.part_no_version", value.getPartNoVersion())));
		// 零件中文名称
		value.setPartNamec(listTmBasPart.get(0).getPartNameC());
		// 零件英文名称
		value.setPartNamee(listTmBasPart.get(0).getPartNameE());
		// 零件英文简称
		value.setPartNamees(listTmBasPart.get(0).getPartNamees());
		// 零件中文简称
		value.setPartNamecs(listTmBasPart.get(0).getPartNamecs());

		value.setCreateTime(new Date());
		value.setCompanyCode(SpringWebUtils.getRequestCompany());
		value.setCreateUser(SpringWebUtils.getRequestUser());
		value.setMarkStatus(1);
		// 预期收货数量==> 实际收货数量
		value.setAsnReceivedQty(0);
		// 预期收货箱数==>实际收货箱数
		value.setReceivePackageNum(0);
		// 预期收货包装容量===>实际收货包装容量
		value.setReceivePackageQty(0);
		// value.setReceivePackageNo(); // 预期收货包装编号 ===>实际收货包装编号
		twDocAsnDetailsDao.insertTwDocAsnDetails(value);
	}

	/**
	 * asn header接收时候，对实际收货的数量进行编辑。编辑的时候只会改变每一行的数量。直到提交的时候会改变行的状态。
	 */
	@Override
	public void updateTwDocAsnDetails(TwDocAsnDetails value, Assist assist) {
		// 实际收货数量
		Integer asnReceivedQty = value.getAsnReceivedQty();
		// 实际收货箱数
		Integer asnPackageNum = value.getReceivePackageNum();
		// 实际收货包装容量
		Integer receivePackageQty = value.getReceivePackageQty();
		if (receivePackageQty * asnPackageNum < asnReceivedQty) {
			throw new ServiceException("实际收货数量不能大于可收货数量");
		}
		TwDocAsnDetails twDocAsnDetails = new TwDocAsnDetails();
		twDocAsnDetails.setTwDocAsnDetailsId(value.getTwDocAsnDetailsId());
		twDocAsnDetails.setAsnReceivedQty(asnReceivedQty);
		twDocAsnDetails.setReceivePackageNum(asnPackageNum);
		twDocAsnDetails.setReceivePackageQty(receivePackageQty);
		twDocAsnDetailsDao.updateNonEmptyTwDocAsnDetailsById(twDocAsnDetails);
	}

	/**
	 * 成品入库 定时任务
	 * 
	 * @param teProductInbound
	 *            teProductInbound
	 * @param headerId
	 *            headerId
	 */
	@Override
	public void insertNonEmptyTwDocAsnDetailsByJob(TeProductInbound teProductInbound, int headerId) {
		TwDocAsnDetails value = new TwDocAsnDetails();
		value.setTwDocAsnHeaderId(headerId);

		TwDocAsnHeader twDocAsnHeader = twDocAsnHeaderDao.selectTwDocAsnHeaderById(value.getTwDocAsnHeaderId());
		List<TwDocAsnDetails> listTwDocAsnDetails = twDocAsnDetailsDao.selectTwDocAsnDetails(
				new Assist(Assist.andEq("tw_doc_asn_details.tw_doc_asn_header_id", value.getTwDocAsnHeaderId())));
		value.setAsnLineno(listTwDocAsnDetails.size() + 1);
		// ASN单证状态（新单0、部分收货1、收货完成2、拒绝收货3、收货取消4、单证关闭5
		value.setLineStatus("0");
		value.setAsnSheetNo(twDocAsnHeader.getAsnSheetNo());

		List<TrBasPartSuppl> listTrBasPartSuppl = trBasPartSupplDao.selectTrBasPartSuppl(
				new Assist(Assist.andEq("part_no_version", teProductInbound.getPartNoVersion())));
		if (listTrBasPartSuppl.size() == 0) {
			throw new ServiceException(teProductInbound.getPartNoVersion() + "零件没有查询到对应的零件供应商关系");
		}
		// 零件供应商关系ID
		value.setTrBasPartSupplId(listTrBasPartSuppl.get(0).getTrBasPartSupplId());
		value.setDeliverySend(listTrBasPartSuppl.get(0).getSupplNo());
		// 后期需要修改
		value.setDeliveryRec("CF");

		// 客户订单号
		value.setCustSheetId(teProductInbound.getSoNo());
		// 客户订单类型
		value.setCustSheetType("14");
		// 客户订单行号
		value.setCustSheetLineId(listTwDocAsnDetails.size() + 1);

		List<TwBasPartBatchHeader> listTwBasPartBatchHeader = twBasPartBatchHeaderDao.selectTwBasPartBatchHeader(
				new Assist(
						Assist.andEq("tw_bas_part_batch_header.part_no_version", teProductInbound.getPartNoVersion())));

		if (listTwBasPartBatchHeader.size() == 0) {
			throw new ServiceException(value.getPartNoVersion() + "零件号，无法查询零件批次属性");
		}

		value.setPartNoVersion(teProductInbound.getPartNoVersion());
		value.setSupplNo(listTwBasPartBatchHeader.get(0).getSupplNo());

		List<TwBasPartBatch> listTwBasPartBatch = twBasPartBatchDao.selectTwBasPartBatch(
				new Assist(Assist.andEq("tw_bas_part_batch.tw_bas_part_batch_header_id",
						listTwBasPartBatchHeader.get(0).getTwBasPartBatchHeaderId())));

		// 是否质检
		String a = "";
		for (TwBasPartBatch twBasPartBatch : listTwBasPartBatch) {
			if ("LOTATT05".equals(twBasPartBatch.getBatchOrder())) {
				a = twBasPartBatch.getIsUsedforLot();
			}
		}
		value.setLotatt02(listTwBasPartBatchHeader.get(0).getPlantNo());
		value.setLotatt03(listTwBasPartBatchHeader.get(0).getWorkshopNo());
		value.setLotatt04(listTwBasPartBatchHeader.get(0).getSupplNo());
		value.setLotatt05(a);

		// 如果新增ASN明细的时候没有填写收货包装流水号（托盘号），那么系统自动生成，生成规则是IS+yyyymmdd+seq
		// receive_pack_serial== 收货包装流水号
		String receivePackSerial = "";
		if (StringUtils.isBlank(value.getReceivePackSerial())) {
			receivePackSerial = jdbcDao.executeProcGetCode("tw_doc_asn_details", "efast");
			value.setReceivePackSerial(receivePackSerial);
		}
		// 如果新增ASN明细的时候没有填写零件包装流水号（箱号），那么系统自动生成，生成规则是入库包装流水号-1-1
		// part_pack_serial 零件包装流水号
		if (StringUtils.isBlank(value.getPartPackSerial())) {
			value.setPartPackSerial(receivePackSerial + "-1-1");
		}

		List<TmBasPart> listTmBasPart = tmBasPartDao.selectTmBasPart(
				new Assist(Assist.andEq("tm_bas_part.part_no_version", teProductInbound.getPartNoVersion())));
		// 零件中文名称
		value.setPartNamec(listTmBasPart.get(0).getPartNameC());
		// 零件英文名称
		value.setPartNamee(listTmBasPart.get(0).getPartNameE());
		// 零件英文简称
		value.setPartNamees(listTmBasPart.get(0).getPartNamees());
		// 零件中文简称
		value.setPartNamecs(listTmBasPart.get(0).getPartNamecs());

		// 预期收货数量
		value.setAsnReqQty(teProductInbound.getPartQty());
		// 预期收货箱数
		value.setAsnPackageNum(1);
		// 预期收货包装容量
		value.setAsnPackageQty(teProductInbound.getPackQty());
		// 预期收货包装编号
		value.setAsnPackageNo(teProductInbound.getPackNo());
		// 预期收货数量==> 实际收货数量
		value.setAsnReceivedQty(0);
		// 预期收货箱数==>实际收货箱数
		value.setReceivePackageNum(0);
		// 预期收货包装容量===>实际收货包装容量
		value.setReceivePackageQty(0);
		// value.setReceivePackageNo(); // 预期收货包装编号 ===>实际收货包装编号

		value.setCreateTime(new Date());
		// value.setCompanyCode(SpringWebUtils.getRequestCompany());
		// value.setCreateUser(SpringWebUtils.getRequestUser());
		value.setMarkStatus(1);

		twDocAsnDetailsDao.insertNonEmptyTwDocAsnDetails(value);
	}

	/**
	 * pda确认收货 业务逻辑和asn收货逻辑一致
	 * 
	 * @param pdaTwDocAsnDetailsBean
	 *            pdaTwDocAsnDetailsBean
	 */
	@Override
	public void twDocAsnDetailsService(PdaTwDocAsnDetailsBean pdaTwDocAsnDetailsBean) {

	}

	@Override
	public long getTwDocAsnDetailsRowCount(Assist assist) {
		return twDocAsnDetailsDao.getTwDocAsnDetailsRowCount(assist);
	}

	@Override
	public List<TwDocAsnDetails> selectTwDocAsnDetails(Assist assist) {
		return twDocAsnDetailsDao.selectTwDocAsnDetails(assist);
	}

	@Override
	public TwDocAsnDetails selectTwDocAsnDetailsByObj(TwDocAsnDetails obj) {
		return twDocAsnDetailsDao.selectTwDocAsnDetailsByObj(obj);
	}

	@Override
	public TwDocAsnDetails selectTwDocAsnDetailsById(Integer id) {
		return twDocAsnDetailsDao.selectTwDocAsnDetailsById(id);
	}

	@Override
	public int insertNonEmptyTwDocAsnDetails(TwDocAsnDetails value) {
		return twDocAsnDetailsDao.insertNonEmptyTwDocAsnDetails(value);
	}

	@Override
	public int insertTwDocAsnDetailsByBatch(List<TwDocAsnDetails> value) {
		return twDocAsnDetailsDao.insertTwDocAsnDetailsByBatch(value);
	}

	@Override
	public int deleteTwDocAsnDetailsById(Integer id) {
		return twDocAsnDetailsDao.deleteTwDocAsnDetailsById(id);
	}

	@Override
	public int deleteTwDocAsnDetails(Assist assist) {
		return twDocAsnDetailsDao.deleteTwDocAsnDetails(assist);
	}

	@Override
	public int updateTwDocAsnDetailsById(TwDocAsnDetails enti) {
		return twDocAsnDetailsDao.updateTwDocAsnDetailsById(enti);
	}

	@Override
	public int updateNonEmptyTwDocAsnDetailsById(TwDocAsnDetails enti) {
		return twDocAsnDetailsDao.updateNonEmptyTwDocAsnDetailsById(enti);
	}

	@Override
	public int updateNonEmptyTwDocAsnDetails(TwDocAsnDetails value, Assist assist) {
		return twDocAsnDetailsDao.updateNonEmptyTwDocAsnDetails(value, assist);
	}

}